home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************/
- /* ip.c ip.c */
- /*************************************************************************/
-
- /* ip.c prints out IP and ARP packets in human readable form */
-
- /* AUTHOR: Vance Morrison
- DATE: 6/5/90 */
-
- static char copywrite[] = "Copywrite (c) 1990, Vance Morrison";
- /*************************************************************************/
-
- #include <stdio.h>
- #include <ctype.h>
- #include <bios.h>
-
- #define swap_word(n) ((((unsigned short) n) >> 8)+(((unsigned short) n) << 8))
-
- #define ARP_REQUEST 1
- #define ARP_REPLY 2
- #define ARP_ETHER_TYPE 1
-
- struct arp {
- unsigned short arp_hdr; /* header type 1 = ETHERNET */
- unsigned short arp_proto; /* protocol code */
- unsigned char arp_hln; /* length of ethernet address */
- unsigned char arp_pln; /* length of ethernet address */
- unsigned short arp_op; /* operation (request reply) */
- unsigned char arp_sha[6]; /* source hardware address */
- unsigned char arp_spa[4]; /* source protocol address */
- unsigned char arp_tha[6]; /* target hardware address */
- unsigned char arp_tpa[4]; /* target protocol address */
- };
-
- #define IP_PROTO_ICMP 1
- #define IP_PROTO_TCP 6
- #define IP_PROTO_UDP 17
-
- struct ip {
- unsigned char ip_ver_size;
- unsigned char ip_tos;
- unsigned short ip_length;
- unsigned short ip_id;
- unsigned short ip_frag;
- unsigned char ip_ttl;
- unsigned char ip_proto;
- unsigned short ip_check;
- unsigned char ip_src[4];
- unsigned char ip_dst[4];
- unsigned char ip_data[1];
- };
-
- struct udp {
- unsigned short udp_src;
- unsigned short udp_dst;
- unsigned short udp_length;
- unsigned short udp_check;
- unsigned char udp_data[1];
- };
-
- /* values for type field */
- #define ICMP_ECHO_REPLY 0
- #define ICMP_ECHO_REQUEST 8
- #define ICMP_TIME 11
- #define ICMP_UNREACHABLE 3
- #define ICMP_REDIRECT 5
-
- /* values for the code field */
- #define ICMP_TIME_TTL 0
- #define ICMP_UNREACH_NET 0
- #define ICMP_UNREACH_HOST 1
- #define ICMP_UNREACH_PROTO 2
- #define ICMP_UNREACH_PORT 3
-
- #define ICMP_REDIRECT_NET 0
- #define ICMP_REDIRECT_HOST 1
- #define ICMP_REDIRECT_TOS_NET 2
- #define ICMP_REDIRECT_TOS_HOST 3
-
- struct icmp {
- unsigned char icmp_type;
- unsigned char icmp_code;
- unsigned short icmp_check;
- unsigned short icmp_id;
- unsigned short icmp_seq;
- };
-
- /* definition of RIP packet structure */
-
- #define RIP_PORT 0x208
-
- #define RIP_REPLY 2
- #define IP_FAMILY 2
-
- struct rip_route {
- unsigned short rip_family;
- unsigned short rip_zero1;
- unsigned char rip_address[4];
- unsigned char rip_zero2[4];
- unsigned char rip_zero3[4];
- unsigned char rip_metric[4];
- };
-
- struct rip {
- unsigned char rip_command;
- unsigned char rip_version;
- unsigned short rip_zero;
- struct rip_route rip_routes[1]; /* routing info */
- };
-
- struct tcp {
- unsigned short tcp_src;
- unsigned short tcp_dst;
- unsigned long tcp_seq;
- unsigned long tcp_ack;
- unsigned char tcp_off;
- unsigned char tcp_flags;
- unsigned short tcp_window;
- unsigned short tcp_check;
- unsigned short tcp_urgent;
- unsigned char tcp_data[1];
- };
-
-
- /******************************************************************/
- print_IP_addr(ip_addr)
- unsigned char *ip_addr;
- {
- char buff[20];
- sprintf(buff, "%d.%d.%d.%d",ip_addr[0],ip_addr[1],ip_addr[2],ip_addr[3]);
- printf("%15s", buff);
- }
-
-
- /******************************************************************/
- print_arp(p)
- struct arp *p;
- {
- unsigned short op;
-
- printf(" ARP PACKET\n");
- printf(" TYPE: %d ", swap_word(p->arp_hdr));
- op = swap_word(p->arp_op);
- printf(" OP: %d ", op);
- if (op == ARP_REQUEST)
- printf("(REQUEST) ");
- else if (op == ARP_REPLY)
- printf("(REPLY) ");
- else
- printf("(UNKNOWN) ");
- printf("\n");
-
- printf(" SOURCE: ETHER ");
- print_ether_addr(p->arp_sha);
- printf(" IP ");
- print_IP_addr(p->arp_spa);
- printf("\n");
-
- printf(" TARGET: ETHER ");
- print_ether_addr(p->arp_tha);
- printf(" IP ");
- print_IP_addr(p->arp_tpa);
- printf("\n");
- }
-
-
- /******************************************************************/
- /* computes the ones complement some of a block of numbers (assumes
- a twos complement 16 bit short integer) */
-
- ones_comp_sum(p, len)
- unsigned short *p;
- int len;
- {
- register unsigned short sum;
- register unsigned short new_sum;
-
- sum = 0;
- while (len > 0) {
- new_sum = sum + *p++;
- if (new_sum < sum) /* did we wrap around */
- new_sum++;
- sum = new_sum;
- --len;
- }
- return(sum);
- }
-
- /**************************************************************************/
- /* pseudo_head_sum, computes the checksum for the psuedo-header given a
- IP packet. This number is used for TCP and UDP checksumming */
-
- unsigned short pseudo_head_sum(p)
- struct ip *p;
- {
- unsigned short data_len;
- unsigned short check;
- unsigned char ttl;
- unsigned short ret;
-
- check = p->ip_check;
- ttl = p->ip_ttl;
-
- p->ip_ttl = 0;
- data_len = swap_word(p->ip_length) - 4*(p->ip_ver_size%16);
- p->ip_check = swap_word(data_len);
- ret = ones_comp_sum((unsigned short *) &p->ip_ttl, 6);
-
- p->ip_check = check;
- p->ip_ttl = ttl;
- return(ret);
- }
-
-
- /******************************************************************/
- print_ip(p)
- struct ip *p;
- {
- unsigned short check, my_check;
-
- printf(" IP PACKET ");
- print_IP_addr(p->ip_src);
- printf(" --> ");
- print_IP_addr(p->ip_dst);
- printf("\n");
-
- printf(" VER:%2d SIZE:%2d ID: %4xH TOS:%3d FRAG/FLAGS: %4xH\n"
- ,(p->ip_ver_size / 16), (p->ip_ver_size % 16), swap_word(p->ip_id),
- p->ip_tos, swap_word(p->ip_frag));
- printf(" LEN:%4d TTL:%3d PROTOCOL:%4d ",
- swap_word(p->ip_length), p->ip_ttl, p->ip_proto);
- switch (p->ip_proto) {
- case IP_PROTO_ICMP:
- printf("(ICMP)");
- break;
- case IP_PROTO_TCP:
- printf("(TCP) ");
- break;
- case IP_PROTO_UDP:
- printf("(UDP) ");
- break;
- default:
- printf(" ");
- break;
- }
-
- check = p->ip_check;
- p->ip_check = 0;
- my_check = ~ones_comp_sum((unsigned short *) p, 10);
- p->ip_check = check;
- printf(" CHECK: %4xH ", swap_word(check));
- if (check == 0)
- printf("(Ignored) ");
- else if (check == my_check)
- printf("(Correct) ");
- else
- printf("(Should be %4x)", swap_word(my_check));
- printf("\n");
-
- switch (p->ip_proto) {
- case IP_PROTO_ICMP:
- print_icmp((struct icmp *) p->ip_data);
- break;
- case IP_PROTO_TCP:
- print_tcp((struct tcp *) p->ip_data,
- swap_word(p->ip_length)-4*(p->ip_ver_size%16));
- break;
- case IP_PROTO_UDP:
- print_udp((struct udp *) p->ip_data);
- break;
- default:
- break;
- }
- }
-
-
- /******************************************************************/
-
- print_udp(p)
- struct udp *p;
- {
-
- printf(" UDP PACKET\n");
- printf(" LEN:%4d SOURCE: %3d DEST %3d: CHECK: %4xH\n",
- swap_word(p->udp_length), swap_word(p->udp_src),
- swap_word(p->udp_dst), swap_word(p->udp_check));
-
- switch (swap_word(p->udp_dst)) {
- case RIP_PORT:
- print_rip((struct rip *) p->udp_data, swap_word(p->udp_length)-8);
- break;
- default:
- break;
- }
- }
-
-
- /******************************************************************/
- print_tcp(p, len)
- struct tcp *p;
- int len;
- {
- printf(" TCP PACKET\n");
- printf(" LEN:%4d SOURCE: %3d DEST %3d: CHECK: %4xH\n",
- len - 20, swap_word(p->tcp_src), swap_word(p->tcp_dst),
- swap_word(p->tcp_check));
- }
-
-
- /******************************************************************/
- print_icmp(p)
- struct icmp *p;
- {
- printf(" ICMP PACKET\n");
- printf(" TYPE:%3d", p->icmp_type);
- switch (p->icmp_type) {
- case ICMP_ECHO_REPLY:
- printf("(ECHO REPLY) ");
- break;
- case ICMP_ECHO_REQUEST:
- printf("(ECHO REQUEST) ");
- break;
- case ICMP_TIME:
- printf("(TIME) ");
- break;
- case ICMP_UNREACHABLE:
- printf("(UNREACHABLE) ");
- break;
- case ICMP_REDIRECT:
- printf("(REDIRECT) ");
- break;
- default:
- printf("(UNKNOWN) ");
- break;
- }
- printf(" CODE:%3d", p->icmp_code);
- }
-
-
- /******************************************************************/
- print_rip(p, len)
- struct rip *p;
- int len;
- {
- int i, num_routes;
-
- printf(" RIP PACKET\n");
- printf(" COMMAND:%3d VERSION:%3d\n",
- p->rip_command, p->rip_version);
-
- num_routes = (len - 4)/20;
- for(i = 0; i < num_routes; i++) {
- printf(" ROUTE: ");
- print_IP_addr(p->rip_routes[i].rip_address);
- printf(" METRIC:%3d", p->rip_routes[i].rip_metric[3]);
- printf(" FAMILY:%3d\n", swap_word(p->rip_routes[i].rip_family));
- }
- }
-
-